﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WFNetLib;
using WFNetLib.Log;
using System.IO;
using System.Globalization;


namespace RobotControl
{
    public enum ParamsListAddr
    {
        深度=0,
        高度=1,
        航向=2,
        
        温度=3,
        频率=4,
        漏水=5,

        定位状态=6,
        纬度=7,
        纬度半球=8,
        经度=9,
        经度半球=10,

        传感器1 = 11,
        传感器2 = 12,
        传感器3 = 13,
        传感器4 = 14,

        时间=15
    }
    public partial class Form_Main : Form
    {
        public Form_Main()
        {
            InitializeComponent();
        }
        RobotData robotData;
        int S, M;
        磁力仪 cly;
        private bool[] ComListening;//是否没有执行完invoke相关操作              
        private bool[] ComClosing;//是否正在关闭串口，执行Application.DoEvents， 并阻止再次invoke 
        private void Form_Main_Load(object sender, EventArgs e)
        {
            robotData = new RobotData(this);
            ComListening = new bool[6];
            ComClosing = new bool[6];
            for (int i = 0; i < 6; i++)
            {
                ComListening[i] = false;
                ComClosing[i] = false;
            }                       
            meter1.Value = 0;
            gpgll.bNMEA0183300 = true;
            List<double> x1 = new List<double>();
            List<double> x2 = new List<double>();
            List<double> x3 = new List<double>();
            List<double> x4 = new List<double>();
            for (int i = 0; i < 10; i++)
            {
                x1.Add(i * 1);
                x2.Add(i * 2);
                x3.Add(i * 3);
                x4.Add(i * 1);
            }
            robotData.LoadDatas(x1, x2, x3, x4);
            S = 4;
            M = 5;
            cly = new 磁力仪(S, M);            

            推进器.k = new int[6];
            推进器.b = new int[6];
            推进器.nk = new int[6];
            推进器.y0 = new int[6];
            推进器.y5 = new int[6];
            推进器.yn5 = new int[6];
            推进器.y0[0] = 0x1ff;
            推进器.yn5[0] = 0x0a8;
            推进器.y5[0] = 0x357;

            推进器.y0[1] = 0x204;
            推进器.yn5[1] = 0x0ab;
            推进器.y5[1] = 0x35a;

            推进器.y0[2] = 0x209;
            推进器.yn5[2] = 0x0b1;
            推进器.y5[2] = 0x361;

            推进器.y0[3] = 0x206;
            推进器.yn5[3] = 0x0b0;
            推进器.y5[3] = 0x35c;

            推进器.y0[4] = 0x202;
            推进器.yn5[4] = 0x0aa;
            推进器.y5[4] = 0x358;

            推进器.y0[5] = 0x203;
            推进器.yn5[5] = 0x0ac;
            推进器.y5[5] = 0x35a;
            for (int i = 0; i < 6; i++)
            {
                推进器.b[i] = 推进器.y0[i];
                推进器.k[i] = (推进器.y5[i] - 推进器.b[i]) / 5;
                推进器.nk[i] = (推进器.yn5[i] - 推进器.b[i]) / -5;
            }
            file = System.Windows.Forms.Application.StartupPath + "\\TextLog\\" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + ".txt";
            FileInfo f = new FileInfo(file);
            if (!Directory.Exists(f.DirectoryName))
                Directory.CreateDirectory(f.DirectoryName);
            this.Text = "水下机器人控制系统" + "----" + f.Name;
            SaveData();
            try
            {
                ShenDuCom.PortName = Properties.Settings.Default.深度计通道;
                ShenDuCom.Open();
            }
            catch { MessageBox.Show("深度计对应串口无法打开，无法获得深度计数据!"); }
            try
            {
                CeJuCom.PortName = Properties.Settings.Default.测距声纳通道;
                CeJuCom.Open();
            }
            catch { MessageBox.Show("测距声纳对应串口无法打开，无法获得测距声纳数据!"); }
            try
            {
                JianCeCom.PortName = Properties.Settings.Default.检测通道;
                JianCeCom.Open();
            }
            catch { MessageBox.Show("磁力仪舱检测对应串口无法打开，无法获得磁力仪舱检测数据!"); }
            try
            {
                string str = Properties.Settings.Default.GPS通道;
                GPSCom.PortName = Properties.Settings.Default.GPS通道;
                GPSCom.Open();
            }
            catch { MessageBox.Show("GPS对应串口无法打开，无法获得GPS数据!"); }
            try
            {
                CiLiYiCOM.PortName = Properties.Settings.Default.磁力计通道;
                CiLiYiCOM.Open();
            }
            catch { MessageBox.Show("磁力仪对应串口无法打开，无法获得磁力仪数据!"); }
            try
            {
                LuoJingCom.PortName = Properties.Settings.Default.磁罗经通道;
                LuoJingCom.Open();
            }
            catch { MessageBox.Show("磁罗经通道对应串口无法打开，无法获得磁罗经数据!"); } 
        }
        static string file;
        private void 测距声纳发射功率设定ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CeJuCom.IsOpen)
            {
                CeJuCom.Close();
                Form_CeJuSetting f = new Form_CeJuSetting(CeJuCom.PortName);
                f.ShowDialog();
                try { CeJuCom.Open(); }
                catch { MessageBox.Show("测距声纳对应串口无法打开，无法获得测距声纳数据!"); } 
            }
            else
                MessageBox.Show("测距声纳对应串口无法打开，无法设定测距声纳!");
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            robotData.AddData();
            Random    random = new Random();
            robotData.SetCurData(ParamsListAddr.深度, random.NextDouble() * 10);
            robotData.SetCurData(ParamsListAddr.纬度, random.NextDouble() * 10);
            robotData.SetCurData(ParamsListAddr.经度, random.NextDouble() * 10);
            robotData.SetCurData(ParamsListAddr.高度, random.NextDouble() * 10);
        }

        private void axCWGraph3D1_CursorChange(object sender, AxCW3DGraphLib._DCWGraph3DEvents_CursorChangeEvent e)
        {
            for (int i = 0; i < robotData.纬度.Count; i++)
            {
                if (robotData.纬度[i] == e.xPosition)
                {
                    if (robotData.经度[i] == e.yPosition)
                    {
                        if (robotData.深度[i] == e.zPosition)
                        {
                            info1.Text = robotData.纬度[i].ToString("F6");
                            info2.Text = robotData.经度[i].ToString("F6");
                            info3.Text = robotData.深度[i].ToString("F1");
                            info4.Text = robotData.高度[i].ToString("F1");
                            info5.Text = robotData.航向[i].ToString("F1");
                            info6.Text = robotData.时间[i].ToString();
                            info7.Text = robotData.传感器1[i].ToString();
                            info8.Text = robotData.传感器2[i].ToString();
                            info9.Text = robotData.传感器3[i].ToString();
                            info10.Text = robotData.传感器4[i].ToString();
                        }
                    }
                }
            }
        }

        private void CiLiYiCOM_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            byte rx;
            if (ComClosing[0])
                return;
            ComListening[0] = true;
            while (CiLiYiCOM.BytesToRead != 0)
            {
                int irx = CiLiYiCOM.ReadByte();
                if (irx == -1)
                    break;
                rx = (byte)irx;
                if (cly.RxProc(rx))
                {
                    long[] arv = new long[4];
                    for (int i = 0; i < S; i++)
                    {
                        arv[i] = 0;
                        for (int j = 0; j < M; j++)
                        {
                            arv[i] += cly.Uncompensated[i, j].ofs_32;
                        }                       
                    }
                    ExternChangeParamList(ParamsListAddr.传感器1, (arv[0] / M * 0.02).ToString());
                    ExternChangeParamList(ParamsListAddr.传感器2, (arv[1] / M * 0.02).ToString());
                    ExternChangeParamList(ParamsListAddr.传感器3, (arv[2] / M * 0.02).ToString());
                    ExternChangeParamList(ParamsListAddr.传感器4, (arv[3] / M * 0.02).ToString());
                }
            }
            ComListening[0] = false;
        }

        private void 磁力仪测试ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (CiLiYiCOM.IsOpen)
            {
                ComClosing[0] = true;
                while (ComListening[0])
                    Application.DoEvents();
                CiLiYiCOM.Close();
                Form_磁力仪测试 f = new Form_磁力仪测试(4, 5);
                f.ShowDialog();
                try { CiLiYiCOM.Open(); }
                catch { MessageBox.Show("磁力仪对应串口无法打开，无法获得磁力仪数据!"); }
            }
            else
                MessageBox.Show("磁力仪对应串口无法打开，无法测试磁力仪!");
        }

        private void Form_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            for (int i = 0; i < 6; i++)
                ComClosing[i] = true;
            for (int i = 0; i < 6; i++)
            {
                while (ComListening[i])
                    Application.DoEvents();
            }
            ShenDuCom.Close();
            CeJuCom.Close();
            JianCeCom.Close();
            GPSCom.Close();
            CiLiYiCOM.Close();
            LuoJingCom.Close();
        }

        private void 磁罗经调零ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (LuoJingCom.IsOpen)
            {
                LuoJingCom.Close();
                Form_CLJTL f = new Form_CLJTL();
                f.ShowDialog();
                try { LuoJingCom.Open(); }
                catch { MessageBox.Show("磁力仪对应串口无法打开，无法获得磁罗经数据!"); }
            }
            else
                MessageBox.Show("磁力仪对应串口无法打开，无法进行磁罗经调零!");
        }

        private void 手柄ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form_Joy f = new Form_Joy();
            f.ShowDialog();
        }
        bool bSave = false;
        void SaveData()
        {            
            if (File.Exists(file))
            {
                robotData.SetCurData(ParamsListAddr.时间, DateTime.Now);
                bSave = true;
                FileStream fs = new FileStream(file, FileMode.Open);
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("{0,-22}", robotData.时间[robotData.时间.Count-1].ToString());
                sb.AppendFormat("{0,-17}", robotData.经度[robotData.经度.Count-1].ToString("F6"));
                sb.AppendFormat("{0,-17}", robotData.纬度[robotData.纬度.Count-1].ToString("F6"));
                sb.AppendFormat("{0,-17}", robotData.深度[robotData.深度.Count-1].ToString("F1"));
                sb.AppendFormat("{0,-17}", robotData.高度[robotData.高度.Count-1].ToString("F1"));
                sb.AppendFormat("{0,-17}", robotData.航向[robotData.航向.Count-1].ToString("F1"));
                sb.AppendFormat("{0,-18}", robotData.传感器1[robotData.传感器1.Count-1].ToString());
                sb.AppendFormat("{0,-18}", robotData.传感器2[robotData.传感器2.Count-1].ToString());
                sb.AppendFormat("{0,-18}", robotData.传感器3[robotData.传感器3.Count-1].ToString());
                sb.AppendFormat("{0,-18}", robotData.传感器4[robotData.传感器4.Count-1].ToString());
                fs.Seek(0, SeekOrigin.End);
                sw.WriteLine(sb.ToString());
                //清空缓冲区
                sw.Flush();
                //关闭流
                sw.Close();
                fs.Close();/**/
                bSave = false;
            }
            else
            {
                FileStream fs = new FileStream(file, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("{0,-20}", "时间");
                sb.AppendFormat("{0,-15}", "经度");
                sb.AppendFormat("{0,-15}", "纬度");
                sb.AppendFormat("{0,-15}", "深度");
                sb.AppendFormat("{0,-15}", "高度");
                sb.AppendFormat("{0,-15}", "航向");
                sb.AppendFormat("{0,-15}", "传感器1");
                sb.AppendFormat("{0,-15}", "传感器2");
                sb.AppendFormat("{0,-15}", "传感器3");
                sb.AppendFormat("{0,-15}", "传感器4");
                fs.Seek(0, SeekOrigin.End);
                sw.WriteLine(sb.ToString());
                //清空缓冲区
                sw.Flush();
                //关闭流
                sw.Close();
                fs.Close();/**/
            } 
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            SaveData();
            MessageBox.Show("当前数据存储成功");
        }

        private void toolStripSeparator1_Click(object sender, EventArgs e)
        {
            file = System.Windows.Forms.Application.StartupPath + "\\TextLog\\" + DateTime.Now.ToString("yyyyMMdd_hhmmss") + ".txt";
            SaveData();
            FileInfo f = new FileInfo(file);
            this.Text = "水下机器人控制系统" + "----" + f.Name;
            MessageBox.Show("新建实验数据文件成功");
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            OpenFileDialog of = new OpenFileDialog();
            FileInfo f = new FileInfo(file);
            of.InitialDirectory = f.DirectoryName;
            if (of.ShowDialog() == DialogResult.OK)
            {
                bSave = true;
                robotData.ClearAll();
                file = of.FileName;
                f = new FileInfo(file);
                this.Text = "水下机器人控制系统" + "----" + f.Name;
                FileStream fs = new FileStream(file, FileMode.Open);
                StreamReader sw = new StreamReader(fs);
                sw.ReadLine();
                while (sw.Peek() >= 0)
                {
                    robotData.LoadData(sw.ReadLine());
                }
                bSave = false;
                Graph3D(robotData.纬度.ToArray(), robotData.经度.ToArray(), robotData.深度.ToArray());
            }
        }
    }
}
